深入了解 http 协议
HTTP/1.1——标准化的协议
- 连接可以复用,节省了多次打开 TCP 连接加载网页文档资源的时间。
- 增加管线化技术,允许在第一个应答被完全发送之前就发送第二个请求,以降低通信延迟。
- 支持响应分块。
- 引入额外的缓存控制机制。
- 引入内容协商机制,包括语言、编码、类型等。并允许客户端和服务器之间约定以最合适的内容进行交换。
- 凭借
Host
标头,能够使不同域名配置在同一个 IP 地址的服务器上。
HTTP 流水线
流水线是在同一条长连接上发出连续的请求,而不用等待应答返回。这样可以避免连接延迟。理论上讲,性能还会因为两个 HTTP 请求有可能被打包到一个 TCP 消息包中而得到提升。就算 HTTP 请求不断的继续,尺寸会增加,但设置 TCP 的最大分段大小(MSS)选项,仍然足够包含一系列简单的请求。
并不是所有类型的 HTTP 请求都能用到流水线:只有幂等方式,比如 GET
、HEAD
、PUT
和 DELETE
能够被安全地重试。如果有故障发生时,流水线的内容要能被轻易的重试。
备注: HTTP 流水线在现代浏览器中并不是默认被启用的:
HTTP/2——为了更优异的表现
- HTTP/2 是二进制协议而不是文本协议。不再可读,也不可无障碍的手动创建,改善的优化技术现在可被实施。
- 这是一个多路复用协议。并行的请求能在同一个链接中处理,移除了 HTTP/1.x 中顺序和阻塞的约束。
- 压缩了标头。因为标头在一系列请求中常常是相似的,其移除了重复和传输重复数据的成本。
- 其允许服务器在客户端缓存中填充数据,通过一个叫服务器推送的机制来提前请求。
Http/2 多路复用
HTTP/2 引入了一个额外的步骤:它将 HTTP/1.x 消息分成帧并嵌入到流(stream)中。数据帧和报头帧分离,这将允许报头压缩。将多个流组合,这是一个被称为多路复用(multiplexing)的过程,它允许更有效的底层 TCP 连接。
Http/2 服务器推送
服务可以主动向客户端发送消息。在浏览器刚请求 HTML
的时候,服务端会把某些资源存在一定的关联性 JS、CSS
等文件等静态资源主动发给客户端,这样客户端可以直接从本地加载这些资源,不用再通过网络再次请求,以此来达到节省浏览器发送 request 请求的过程。
使用服务器推送
1 | Link: </css/styles.css>; rel=preload; as=style, |
可以看到服务器initiator中的 push 状态表示这是服务端进行主动推送。
1 | 对于主动推送的文件势必会带来多余或已经浏览器已有一份的文件 |
客户端使用一个简洁的 Cache Digest 来告诉服务器,哪些东西已经在缓存,因此服务器也就会知道哪些是客户端所需要的。
Http/2 缺点
- TCP 以及 TCP+TLS 建立连接的延迟(握手延迟)
- http2.0 中 TCP 的队头阻塞依然没有彻底解决,连接双方的有任一个数据包丢失,或任一方的网络中断,整个 TCP 连接就会暂停,丢失的数据包需要被重新传输,从而阻塞该 TCP 连接中的所有请求,反而在网络较差或不稳定情况下,使用多个连接表现更好。
HTTP/3——基于 QUIC 的 HTTP
- Real Streams:是实际的直接数据传输速度提升;
- 改进的握手:是连接建立速度的改进;
- 连接迁移:减少必要的重新连接次数,从而减少会话之间的连接建立和数据丢失,从而提高速度;
Real Streams
因为在 TCP 中,所有数据包都在“线路”中传输,如果一个数据包变慢或丢失,则整个“线路”必须等待慢速/丢失的数据包回到其位置并继续前进。尽管 TCP 有流的概念,但它们不是真正的流,而是模拟它们的抽象。多个文件被分解成数据包,数据包被分组在小帧中,但无论如何都通过“行”中的单个流。
QUIC 实现了 streams,这是真正的 stream。所有的数据将真正通过一个连接但是多个流在流动。例如:JS bundle 文件可能是一个流并标记另一个流
除了通过真正并行化数据包传输来提高速度之外,还有一个恼人的问题已经解决。线路阻塞的头。
你知道,当你匆忙在你的杂货店排队时。前面有一个超级慢的人,只会减慢整条线的速度。嗯,这就是 HoL Blocking。
当单个(慢速)对象阻止其他/后续对象取得进展时
HTTP 的所有版本,都以某种方式在不同级别上遭受了行头阻塞 (HoL)。在 HTTP/2 中,由于单流性质,它是 TCP HoL 阻塞。
QUIC 并没有真正解决 HoL 阻塞问题,而是将它移到了另一个地方。虽然它没有完全解决问题,但这种转变显着提高了性能。
HoL 阻塞可能发生在流级别。因为流顺序仍然很重要,所以您不能重新排序或丢失数据包。因此,如果流中有一个慢家伙,流将无法继续,必须等待……但在这种情况下,它不会阻塞其他流。一旦烦人的数据包问题得到解决,流就会恢复。
握手
QUIC 至少需要少一次握手。新连接只需要一次握手,恢复连接不需要握手。这使得 QUIC 1RTT 用于新连接,0RTT 用于恢复。
安全
HTTP 是纯文本协议。它只是通过电线(或无线电波)发送文本。HTTPS 中的 S 代表 Secure。通过使用 HTTPS,我们指示浏览器使用 TLS 协议参与通信。TLS 协议将使用高级数学算法加密我们的数据。这样可以确保即使数据可能被第三方拦截,也没有用。现在,Internet 上的大多数 Web 资源都使用 HTTPS。
即使现代浏览器坚持使用 HTTPS,我们仍然可以避免它。
对于 QUIC,这是不可避免的。因为 TLS 是内置在 QUIC 中的。因此对于 HTTP/3,将不再需要https://
和端口433
。开箱即用的一切都将被加密。而且没有办法关闭加密。
连接迁移
连接迁移:当客户端切换网络时,和服务器的连接并不会断开,仍然可以正常通信,对于 TCP 协议而言,这是不可能做到的。因为 TCP 的连接基于 4 元组:源 IP、源端口、目的 IP、目的端口,只要其中 1 个发生变化,就需要重新建立连接。但 QUIC 的连接是基于 64 位的 Connection ID,网络切换并不会影响 Connection ID 的变化,连接在逻辑上仍然是通的